import {
    Injectable,
    NestInterceptor,
    ExecutionContext,
    CallHandler,
    HttpException,
    HttpStatus,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { validateAndDecrypt } from '../decrypt/decrypt.utils';

@Injectable()
export class LicenseInterceptor implements NestInterceptor {
    private licenseCache: { isValid: boolean; lastCheck: number } = {
        isValid: true,
        lastCheck: 0
    };

    // 缓存检查间隔（1分钟）
    private readonly CACHE_INTERVAL = 1 * 60 * 1000;

    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        // 检查许可证
        if (!this.checkLicense()) {
            return throwError(() => new HttpException({
                statusCode: HttpStatus.SERVICE_UNAVAILABLE,
                message: '许可证已过期，服务不可用',
                error: 'License Expired'
            }, HttpStatus.SERVICE_UNAVAILABLE));
        }

        return next.handle().pipe(
            catchError(error => {
                // 如果是许可证相关错误，记录并返回统一错误
                if (error.message?.includes('许可证')) {
                    console.error('❌ 许可证错误:', error.message);
                    return throwError(() => new HttpException({
                        statusCode: HttpStatus.SERVICE_UNAVAILABLE,
                        message: '服务不可用',
                        error: 'Service Unavailable'
                    }, HttpStatus.SERVICE_UNAVAILABLE));
                }
                return throwError(() => error);
            })
        );
    }

    /**
     * 检查许可证是否有效
     * @returns 许可证是否有效
     */
    private checkLicense(): boolean {
        const now = Date.now();

        // 如果缓存还有效，直接返回缓存结果
        if (now - this.licenseCache.lastCheck < this.CACHE_INTERVAL) {
            return this.licenseCache.isValid;
        }

        try {
            // 尝试验证许可证，如果过期会抛出异常
            const result = validateAndDecrypt();

            // 如果执行到这里，说明许可证有效
            this.licenseCache.isValid = true;
            this.licenseCache.lastCheck = now;
            return true;
        } catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);

            if (errorMessage.includes('许可证已过期')) {
                console.error('❌ 许可证已过期，服务将停止运行');
            } else {
                console.error('❌ 许可证验证失败:', errorMessage);
            }

            this.licenseCache.isValid = false;
            this.licenseCache.lastCheck = now;

            // 延迟停止服务，确保响应能返回
            setTimeout(() => {
                console.error('🛑 正在停止服务...');
                process.exit(1);
            }, 5000);

            return false;
        }
    }
} 